const $base = {
  deepClone: function (data) {
    var result;
    var obj = $base.isClass(data);
    if (obj === 'Object') {
      result = {};
    } else {
      if (obj === 'Array') {
        result = [];
      } else {
        return data;
      }
    }
    for (var r in data) {
      if (!data.hasOwnProperty(r)) {
        continue;
      }
      var t = data[r],
        q = $base.isClass(t);
      if (q === 'Object') {
        result[r] = arguments.callee(t);
      } else {
        if (q === 'Array') {
          result[r] = arguments.callee(t);
        } else {
          result[r] = data[r];
        }
      }
    }
    return result;
  },
  isClass: function (obj) {
    if (obj === null) {
      return 'Null';
    }
    if (obj === undefined) {
      return 'Undefined';
    }
    return Object.prototype.toString.call(obj).slice(8, -1);
  },
  arrayToTree: function (items) {
    const result = []; // 存放结果集
    const itemMap = {}; //
    for (const item of items) {
      const id = item.id;
      const pid = item.pid;
      if (!itemMap[id]) {
        itemMap[id] = {
          children: [],
        };
      }
      itemMap[id] = {
        ...item,
        children: itemMap[id]['children'],
      };
      const treeItem = itemMap[id];
      if (pid === 0) {
        result.push(treeItem);
      } else {
        if (!itemMap[pid]) {
          itemMap[pid] = {
            children: [],
          };
        }
        itemMap[pid].children.push(treeItem);
      }
    }
    return result;
  },
  /**
   * 筛选 树形结构
   * @param {array} nodes 列表
   * @param {string||number} query 需要查询的值
   * @param {string} field 字段名
   * @param {number} type 1：带父节点，2:不带父节点
   * @returns
   */
  filterTree: function (nodes, query, field, type) {
    // 条件就是节点的title过滤关键字
    let predicate = function (node) {
      let fieldV = node[field];
      if (typeof fieldV === 'number') {
        fieldV += '';
      }
      if (fieldV?.includes(query)) {
        return true;
      } else {
        return false;
      }
    };

    // 结束递归的条件
    if (!(nodes && nodes.length)) {
      return [];
    }
    let newChildren = [];
    for (let node of nodes) {
      //一、带父节点     以下两个条件任何一个成立，当前节点都应该加入到新子节点集中
      // 1. 子孙节点中存在符合条件的，即 subs 数组中有值
      // 2. 自己本身符合条件
      if (type === 1) {
        let subs = $base.filterTree(node.children, query, field, type);
        if (predicate(node)) {
          newChildren.push(node);
        } else if (subs && subs.length) {
          node.children = subs;
          newChildren.push(node);
        }
      } else {
        //二、不带父节点     以下只需要考虑自身的节点满足条件即可,不用带上父节点
        if (predicate(node)) {
          newChildren.push(node);
          node.children = $base.filterTree(node.children, query, field, type);
        } else {
          newChildren.push(...$base.filterTree(node.children, query, field, type));
        }
      }
    }
    return newChildren.length ? newChildren : [];
  },

  // 常用正则规则大全：https://any86.github.io/any-rule/

  rules: {
    isPhone(value) {
      const reg = /^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/;
      return reg.test(value);
    },
    isMobile(value) {
      const regM = /^(?:(?:\d{3}-)?\d{8}|^(?:\d{4}-)?\d{7,8})(?:-\d+)?$/;
      return regM.test(value);
    },
    isEmail(value) {
      const reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
      return reg.test(value);
    },
    isIdCard(value) {
      const reg = /(^\d{8}(0\d|10|11|12)([0-2]\d|30|31)\d{3}$)|(^\d{6}(18|19|20)\d{2}(0[1-9]|10|11|12)([0-2]\d|30|31)\d{3}(\d|X|x)$)/;
      return reg.test(value);
    },
    isLettersNum(value) {
      //内容须是字母或数字组成
      const reg = /^[A-Za-z0-9]+$/;
      return reg.test(value);
    },
    isNumber(value) {
      const reg = /^\d{1,}$/;
      return reg.test(value);
    },
    isMoney(value) {
      // 内容是否金额类型
      const reg = /^-?\d+(,\d{3})*(\.\d{1,2})?$/;
      return reg.test(value);
    },
    isUscc(value) {
      const reg = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/;
      return reg.test(value);
    },
    isPwd(value) {
      // 大写字母，小写字母，数字，特殊符号 `@#$%^&*`~()-+=` 中任意3项密码
      const reg = /^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\W_!@#$%^&*`~()-+=]+$)(?![0-9\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\W_!@#$%^&*`~()-+=]/;
      return reg.test(value);
    },
  },
  removeLoading: function (p, r, i) {
    if (p === undefined) {
      p = 'body';
    }
    if (r === undefined) {
      r = true;
    }
    var q = $(p).children('.page-loading');
    if (i) {
      q.remove();
    } else {
      if (r) {
        q.fadeOut('fast');
      } else {
        q.hide();
      }
    }
    $(p).removeClass('page-no-scroll');
  },
};
const $required = (message, trigger = 'change') => ({
  required: true,
  message,
  trigger,
});

/**
 * 存在校验
 * @param message 提示
 * @param type phone|phoneOrMobile|email|idCard|number|lettersNum|uscc|money|pwd
 */
const $existRules = (message, type, rule) => ({
  required: false,
  message,
  trigger: 'change',
  validator(value) {
    if (value) {
      let flag = true;
      switch (type) {
        case 'phone':
          flag = $base.rules.isPhone(value);
          break;
        case 'mobile':
          flag = $base.rules.isMobile(value);
          break;
        case 'phoneOrMobile':
          flag = $base.rules.isMobile(value) || $base.rules.isPhone(value);
          break;
        case 'email':
          flag = $base.rules.isEmail(value);
          break;
        case 'idCard':
          flag = $base.rules.isIdCard(value);
          break;
        case 'number':
          flag = $base.rules.isNumber(value);
          break;
        case 'lettersNum':
          flag = $base.rules.isLettersNum(value);
          break;
        case 'uscc':
          flag = $base.rules.isUscc(value);
          break;
        case 'money':
          flag = $base.rules.isMoney(value);
          break;
        case 'pwd':
          flag = $base.rules.isPwd(value);
          break;
        default:
          if (rule) {
            flag = rule.test(value);
          }
          break;
      }
      if (flag) {
        return { result: true };
      }
      return { result: false, message, type: 'error' };
    } else {
      return { result: true };
    }
  },
});

const genRandomId = () => Number(Math.random().toString().substr(3, 5) + Date.now()).toString(36);
